﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using M3G;

/**
 * サンプリングのテストは別ファイル(TestSamplingKeyframe.cs)
 * */


namespace MyTestProject {

    public class TestKeyframe {
        [Fact]
        public void TestConstructor1 () {
            var kseq = new KeyframeSequence (4, 3, KeyframeSequence.Step);

            Assert.Equal (1, kseq.ChanelCount);
            Assert.Equal (4, kseq.KeyframeCount);
            Assert.Equal (3, kseq.ComponentCount);
            Assert.Equal (0, kseq.Duration);
            Assert.Equal (0, kseq.EventCount);
            Assert.Equal (KeyframeSequence.Step, kseq.InterpolationType);
            Assert.Equal (KeyframeSequence.Constant, kseq.RepeatMode);
            Assert.Equal (0, kseq.ValidRangeFirst);
            Assert.Equal (3, kseq.ValidRangeLast);
        }

        [Fact]
        public void TestConstructor2 () {
            var kseq = new KeyframeSequence (4, 4, 3, KeyframeSequence.Step);

            Assert.Equal (4, kseq.ChanelCount);
            Assert.Equal (4, kseq.KeyframeCount);
            Assert.Equal (3, kseq.ComponentCount);
            Assert.Equal (0, kseq.Duration);
            Assert.Equal (0, kseq.EventCount);
            Assert.Equal (KeyframeSequence.Step, kseq.InterpolationType);
            Assert.Equal (KeyframeSequence.Constant, kseq.RepeatMode);
            Assert.Equal (0, kseq.ValidRangeFirst);
            Assert.Equal (3, kseq.ValidRangeLast);
        }

        [Fact]
        public void TestGetEventCount () {
            var kseq = new KeyframeSequence (4, 3, KeyframeSequence.Step);
            kseq.AddEvent (100, 5);

            Assert.Equal (1, kseq.EventCount);
        }

        [Fact]
        public void TestAddEvent () {
            var kseq = new KeyframeSequence (4, 3, KeyframeSequence.Step);
            kseq.AddEvent (100, 1);  // (time, id)
            kseq.AddEvent (300, 2);
            kseq.AddEvent (200, 3);

            // evnetは内部で自動的にtimeの順にソートされる
            Assert.Equal (3, kseq.EventCount);
            Assert.Equal (100, kseq.EventTime[0]);
            Assert.Equal (200, kseq.EventTime[1]);
            Assert.Equal (300, kseq.EventTime[2]);
            Assert.Equal (1, kseq.EventID[0]);
            Assert.Equal (3, kseq.EventID[1]);
            Assert.Equal (2, kseq.EventID[2]);
        }


        [Fact]
        public void TestRemoveEvent () {
            var kseq = new KeyframeSequence (4, 3, KeyframeSequence.Step);
            kseq.AddEvent (100, 6);
            kseq.AddEvent (200, 5);
            
            kseq.RemoveEvent (0);   // (100,6)を削除

            Assert.Equal (1, kseq.EventCount);
            Assert.Equal (200, kseq.EventTime[0]);
            Assert.Equal (5, kseq.EventID[0]);

        }

        [Fact]
        public void TestSetDuration () {
            var kseq = new KeyframeSequence (4, 3, KeyframeSequence.Step);
            kseq.Duration = 100;

            Assert.Equal (100, kseq.Duration);
        }



        [Fact]
        public void TestGetKeyframe () {
            var kseq = new KeyframeSequence (4, 3, KeyframeSequence.Step);
            var time = 100;
            var value = new float[] { 1, 2, 3 };
            kseq.SetKeyframe (1, time, value);

            int outTime;
            var outValue  = new float[3];
            outTime = kseq.GetKeyframe (1, outValue);

            Assert.Equal (time, outTime);
            Assert.Equal (value, outValue);
        }

        [Fact]
        public void TestSetKeyframeChannel () {
            var kseq = new KeyframeSequence (4, 4, 3, KeyframeSequence.Step);
            var time = 100;
            var value1 = new float[] { 1, 2, 3 };
            var value2 = new float[] { 4, 5, 6 };
            kseq.SetKeyframeTime (0, time);
            kseq.SetKeyframeValue (0, 0, value1);
            kseq.SetKeyframeValue (1, 0, value2);

            int outTime1;
            int outTime2;
            var outValue1 = new float[3];
            var outValue2 = new float[3];
            outTime1 = kseq.GetKeyframe (0, 0, outValue1);
            outTime2 = kseq.GetKeyframe (1, 0, outValue2);

            Assert.Equal (time, outTime1);
            Assert.Equal (value1, outValue1);

            Assert.Equal (time, outTime2);
            Assert.Equal (value2, outValue2);
        }

        [Fact]
        public void TestSetRepeatMode () {
            var kseq = new KeyframeSequence (4, 4, 3, KeyframeSequence.Step);
            kseq.RepeatMode = KeyframeSequence.Loop;

            Assert.Equal (KeyframeSequence.Loop, kseq.RepeatMode);
        }

        [Fact]
        public void TestSetValidRange () {
            var kseq = new KeyframeSequence (4, 4, 3, KeyframeSequence.Step);
            kseq.SetValidRange (2, 3);

            Assert.Equal (2, kseq.ValidRangeFirst);
            Assert.Equal (3, kseq.ValidRangeLast);
        }

        [Fact]
        public void TestDuplicate () {
            var time = 100;
            var value = new float[] { 1, 2, 3 };
            var kseq = new KeyframeSequence (2, 4, 3, KeyframeSequence.Step);

            kseq.Duration = 100;
            kseq.RepeatMode = KeyframeSequence.Loop;
            kseq.SetValidRange (2, 3);
            kseq.SetKeyframeTime (1, time);
            kseq.SetKeyframeValue (1, 0, value);
            kseq.AddEvent (100, 5);
            kseq.UserID = 100;

            var dup = (KeyframeSequence)kseq.Duplicate ();

            Assert.Equal (kseq.ChanelCount, dup.ChanelCount);
            Assert.Equal (kseq.KeyframeCount, dup.KeyframeCount);
            Assert.Equal (kseq.ComponentCount, dup.ComponentCount);
            Assert.Equal (kseq.Duration, dup.Duration);
            Assert.Equal (kseq.EventCount, dup.EventCount);
            Assert.Equal (kseq.InterpolationType, dup.InterpolationType);
            Assert.Equal (kseq.RepeatMode, dup.RepeatMode);
            Assert.Equal (kseq.ValidRangeFirst, dup.ValidRangeFirst);
            Assert.Equal (kseq.ValidRangeLast, dup.ValidRangeLast);
            Assert.Equal (kseq.UserID, dup.UserID);
        }

    }
}
